package com.atguigu.c_designed.m1createModel.c1singleton;

/**
 * 单例设计模式介绍
 * 所谓类的单例设计模式，就是采取一定的方法保证在整个的软件系统中，对某个类只能存在一个对象实例，
 * 并且该类只提供一个取得其对象实例的方法(静态方法)。
 * 单例模式有八种方式：
 * 1) 饿汉式(静态常量)
 * 2) 饿汉式（静态代码块）
 * 3) 懒汉式(线程不安全)
 * 4) 懒汉式(线程安全，同步方法)
 * 5) 懒汉式(线程安全，同步代码块)
 * 6) 双重检查
 * 7) 静态内部类
 * 8) 枚举
 * <p>
 * 实现
 * 1) 构造器私有化 (防止 new )
 * 2) 类的内部创建对象
 * 3) 向外暴露一个静态的公共方法。aaagetInstance
 */
public class Singleton03 {

    public static void main(String[] args) {
        //测试
        LazySingleton03 instance = LazySingleton03.getInstance();
        LazySingleton03 instance2 = LazySingleton03.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println("instance.hashCode=" + instance.hashCode());
        System.out.println("instance2.hashCode=" + instance2.hashCode());
    }
}

/**
 * 优缺点说明：
 * 1) 起到了 Lazy Loading 的效果，但是只能在单线程下使用。
 * 2) 如果在多线程下，一个线程进入了 if (singleton == null)判断语句块，还未来得及往下执行，另一个线程也通过
 * 了这个判断语句，这时便会产生多个实例。所以在多线程环境下不可使用这种方式
 * 3) 结论：在实际开发中，不要使用这种方式.
 */
// 懒汉式
class LazySingleton03 {
    //构造器私有化
    private LazySingleton03() {
    }

    //本类内部创建对象实例
    private static LazySingleton03 instance;

    //    提供获取实例的方法
    public static LazySingleton03 getInstance() {
        if (instance == null) {
            instance = new LazySingleton03();
        }
        return instance;
    }
}
